﻿using Coldairarrow.Business.TD;
using Coldairarrow.Entity.TD;
using Coldairarrow.IBusiness.DTO;
using Coldairarrow.Util;
using Elasticsearch.Net;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Coldairarrow.IBusiness;
using Microsoft.Extensions.DependencyInjection;
using Coldairarrow.Business.PB;
using Coldairarrow.Business.PD;
using Coldairarrow.Entity.DTO;
using NPOI.HSSF.UserModel;
using NPOI.SS.UserModel;
using NPOI.SS.Util;
using Coldairarrow.Util.ClassLibrary;
using Microsoft.Extensions.Options;

namespace Coldairarrow.Api.Controllers.TD
{
    [Route("/TD/[controller]/[action]")]
    public class TD_InStorageController : BaseApiController
    {
        #region DI

        public TD_InStorageController(ITD_InStorageBusiness tD_InStorageBus, IOperator op, IServiceProvider svcProvider, IOptions<MongoDBOptions> mongodbOptions)
        {
            _tD_InStorageBus = tD_InStorageBus;
            _Op = op;
            this.serviceProvider = svcProvider;
            _mongodbOptions = mongodbOptions.Value;
        }
        IServiceProvider serviceProvider { get; }
        ITD_InStorageBusiness _tD_InStorageBus { get; }
        IOperator _Op { get; }

        private readonly MongoDBOptions _mongodbOptions;

        #endregion

        #region 获取

        [HttpPost]
        public async Task<PageResult<TD_InStorage>> GetDataList(TD_InStoragePageInput input)
        {
            input.StorId = _Op.Property.DefaultStorageId;
            return await _tD_InStorageBus.GetDataListAsync(input);
        }
        /// <summary>
        /// 获取入库汇总信息
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<PageResultData<inStorDetailDto>> inStorDetailDetail(PageInput<ProjectSummaryContionDTO> input)
        {
            return await _tD_InStorageBus.inStorDetailDetail(input);
        }
        /// <summary>
        /// 完工入库列表
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<PageResult<TD_InStorage>> GetDataListAsyncGroup(TD_InStoragePageInput input)
        {
            input.StorId = _Op.Property.DefaultStorageId;
            return await _tD_InStorageBus.GetDataListAsyncGroup(input);
        }
        /// <summary>
        /// 提交审核
        /// </summary>
        /// <returns></returns>
        [HttpGet]

        public async Task<AjaxResult> SaveToExamine(string idIn, bool judge)
        {
            return await _tD_InStorageBus.SaveToExamine(idIn, judge);

        }
        /// <summary>
        /// 获取报废出库列表数据
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<PageResult<TD_InStorage>> GetDataListAsyncScrap(TD_InStoragePageInput input) {
            return await _tD_InStorageBus.GetDataListAsyncScrap(input);
        }

        [HttpPost]
        public async Task<TD_InStorage> GetTheData(IdInputDTO input)
        {
            return await _tD_InStorageBus.GetTheDataAsync(input.id);
        }
        /// <summary>
        /// 打印完工入库接口
        /// </summary>
        /// <param name="ParentId"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<TD_InStorageinfo> GetTD_InStorageinfo(string ParentId)
        {
            return await _tD_InStorageBus.GetTD_InStorageinfo(ParentId);
        }

        //入库汇总导出
        [HttpGet]
        public async Task<IActionResult> GetReceiptSummaryExport(string MaterialNameOrCode,string ProjectName,DateTime? OrderTimeStart,DateTime? OrderTimeEnd,string StrareaName)
        {
            //输入搜索条件
            PageInput<ProjectSummaryContionDTO> input = new PageInput<ProjectSummaryContionDTO>();
            input.Search.MaterialNameOrCode = MaterialNameOrCode;
            input.Search.ProjectName = ProjectName;
            input.Search.OrderTimeStart = OrderTimeStart;
            input.Search.OrderTimeEnd = OrderTimeEnd;
            input.Search.StrareaName = StrareaName;
            //查询数据
            var  listFaultInfo = await _tD_InStorageBus.inStorDetailDetail(input);
            //二：代码创建一个Excel表格（这里称为工作簿）
            //创建Excel文件的对象 工作簿(调用NPOI文件)
            HSSFWorkbook excelBook = new HSSFWorkbook();
            //创建Excel工作表 Sheet=故障码信息
            //标题
            ISheet sheet1 = excelBook.CreateSheet("入库汇总导出");
            sheet1.AddMergedRegion(new CellRangeAddress(0, 0, 0, 7));//合并单元格,4个参数依次为为startRow,endRow,startCol,endCo
            IRow ROW = sheet1.CreateRow(0);
            Double? TotalStockin= 0;
            Double? TotalWarehousingamount = 0;
            for (int i = 0; i < listFaultInfo.Data.Count; i++) {
                TotalStockin += listFaultInfo.Data[i].Num;
                TotalWarehousingamount+= listFaultInfo.Data[i].materialPrice;
            }
            ROW.CreateCell(0).SetCellValue($"入库总数:{TotalStockin}      入库总额:{TotalWarehousingamount} ");
            IRow row5Temp = sheet1.CreateRow(1);
            row5Temp.CreateCell(0).SetCellValue("仓库");
            row5Temp.CreateCell(1).SetCellValue("编号");
            row5Temp.CreateCell(2).SetCellValue("名称");
            row5Temp.CreateCell(3).SetCellValue("规格");
            row5Temp.CreateCell(4).SetCellValue("入库数量");
            row5Temp.CreateCell(5).SetCellValue("入库重量(kg)");
            row5Temp.CreateCell(6).SetCellValue("单重");
            //给Sheet(清单信息）添加第一行的头部标题
            IRow row1 = sheet1.CreateRow(6);

            for (int i = 0; i < listFaultInfo.Data.Count; i++)
            {

                //sheet1.CreateRow(i).
                //创建行
                IRow rowTemp = sheet1.CreateRow(i + 2);
                rowTemp.Height = 600;

                //入库仓库
                rowTemp.CreateCell(0).SetCellValue(listFaultInfo.Data[i].Warehouse);
                //物料编号
                rowTemp.CreateCell(1).SetCellValue(listFaultInfo.Data[i].materialCode);



                //物料名称
                rowTemp.CreateCell(2).SetCellValue(listFaultInfo.Data[i].MaterName);
                
                //单位
                rowTemp.CreateCell(3).SetCellValue(listFaultInfo.Data[i].materialSpce);
                //入库数量
                rowTemp.CreateCell(4).SetCellValue(Convert.ToDouble(listFaultInfo.Data[i].Num));
                //物料理论重量
                rowTemp.CreateCell(5).SetCellValue(Convert.ToDouble(listFaultInfo.Data[i].materialWeight.ToString()));
              
                //单重
                rowTemp.CreateCell(6).SetCellValue(Convert.ToDouble(listFaultInfo.Data[i].Weight.ToString()));
           
               
            }
            //输出的文件名称
            string fileName = "入库汇总导出" + DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss-ffff") + ".xls";
            //把Excel转为流，输出
            //创建文件流
            System.IO.MemoryStream bookStream = new System.IO.MemoryStream();
            //将工作薄写入文件流
            excelBook.Write(bookStream);

            //输出之前调用Seek（偏移量，游标位置) 把0位置指定为开始位置
            bookStream.Seek(0, System.IO.SeekOrigin.Begin);
            //Stream对象,文件类型,文件名称
            return File(bookStream, "application/vnd.ms-excel", fileName);
        }
        #endregion

        #region 提交

        [HttpPost]
        public async Task SaveData(TD_InStorage data)
        {
            double num = 0;
            if (data.Id.IsNullOrEmpty())
            {
                InitEntity(data);
                foreach (var item in data.InStorDetails)
                {
                    InitEntity(item);
                    item.InStorId = data.Id;
                    item.StorId = data.StorId;
                    item.TotalAmt = item.Price * item.Num;
                    num += item.Num;
                }
                data.TotalNum = num;
                await _tD_InStorageBus.AddDataAsync(data);
            }
            else
            {
                foreach (var item in data.InStorDetails)
                {
                    if (item.Id.StartsWith("newid_"))
                        InitEntity(item);
                    item.InStorId = data.Id;
                    item.StorId = data.StorId;
                    item.TotalAmt = item.Price * item.Num;
                    num += item.Num;
                }
                data.TotalNum = num;
                await _tD_InStorageBus.UpdateDataAsync(data);
            }
        }
        /// <summary>
        /// 自动入库
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<AjaxResult<TD_InStorage>> AutoInByTary(AutoInStorageByTary data)
        {
            var traySvc = this.serviceProvider.GetRequiredService<IPB_TrayBusiness>();
            var tray = await traySvc.GetByCode(data.TrayCode);
            if (tray == null || !tray.LocalId.IsNullOrEmpty())
                return new AjaxResult<TD_InStorage>() { Success = false, Msg = "托盘编号错误或者托盘已入库" };
            //var planSvc = this.serviceProvider.GetRequiredService<IPD_PlanBusiness>();
            //var plan = await planSvc.GetByCode(data.PlanCode);
            var materialSvc = this.serviceProvider.GetRequiredService<IPB_MaterialBusiness>();
            var material = await materialSvc.GetByBarcode(data.MaterialCode);
            var StorId = _Op.Property.DefaultStorageId;

            if (tray == null || material == null) return new AjaxResult<TD_InStorage>() { Success = false, Msg = "托盘或物料输入不正确" };
            (string StorId, string MaterialId, string TaryId) para = (StorId, material.Id, tray.Id);
            var localId = await _tD_InStorageBus.ReqLocation(para);
            if (localId.IsNullOrEmpty()) return new AjaxResult<TD_InStorage>() { Success = false, Msg = "没有可以入库的货位" };

            var entity = new TD_InStorage()
            {
                RecId = data.RecId,
                InStorTime = DateTime.Now,
                InType = "Product",
                //RefCode = data.PlanCode,
                Status = 0,
                StorId = StorId,
                //SupId = data.SupId,
                InStorDetails = new List<TD_InStorDetail>() {
                    new TD_InStorDetail(){
                        StorId=StorId,
                        LocalId=localId,
                      //  TrayId=tray.Id,
                        MaterialId=material.Id,
                        BatchNo=data.BatchNo,
                        Num=data.Num
                    }
                }
            };

            InitEntity(entity);
            foreach (var item in entity.InStorDetails)
            {
                InitEntity(item);
                item.InStorId = entity.Id;
                item.TotalAmt = item.Price * item.Num;
            }
            await _tD_InStorageBus.AddDataAsync(entity);

            return Success<TD_InStorage>(entity);
        }

        /// <summary>
        /// 手动入库
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<AjaxResult<TD_InStorage>> ManualIn(ManualInStorage data)
        {

            string trayId = null;
            if (!data.TrayCode.IsNullOrEmpty())
            {
                var traySvc = this.serviceProvider.GetRequiredService<IPB_TrayBusiness>();
                var tray = await traySvc.GetByCode(data.TrayCode);
                if (tray == null || !tray.LocalId.IsNullOrEmpty())
                    return new AjaxResult<TD_InStorage>() { Success = false, Msg = "托盘编号错误或者托盘已入库" };
                trayId = tray.Id;
            }
            //var planSvc = this.serviceProvider.GetRequiredService<IPD_PlanBusiness>();
            //var plan = await planSvc.GetByCode(data.PlanCode);
            var materialSvc = this.serviceProvider.GetRequiredService<IPB_MaterialBusiness>();
            var material = await materialSvc.GetByBarcode(data.MaterialCode);

            var StorId = _Op.Property.DefaultStorageId;

            var localSvc = this.serviceProvider.GetRequiredService<IPB_LocationBusiness>();
            var location = await localSvc.GetByCode(StorId, data.LocalCode);

            if (material == null || location == null) return new AjaxResult<TD_InStorage>() { Success = false, Msg = "物料或货位输入不正确" };


            var entity = new TD_InStorage()
            {
                RecId = data.RecId,
                InStorTime = DateTime.Now,
                InType = "Product",
                //RefCode = data.PlanCode,
                Status = 0,
                StorId = StorId,
                //SupId = data.SupId,
                InStorDetails = new List<TD_InStorDetail>() {
                    new TD_InStorDetail(){
                        StorId=StorId,
                        LocalId=location.Id,
                        //TrayId=trayId,
                        MaterialId=material.Id,
                        BatchNo=data.BatchNo,
                        Num=data.Num
                    }
                }
            };

            InitEntity(entity);
            foreach (var item in entity.InStorDetails)
            {
                InitEntity(item);
                item.InStorId = entity.Id;
                item.TotalAmt = item.Price * item.Num;
            }
            await _tD_InStorageBus.AddDataAsync(entity);

            return Success<TD_InStorage>(entity);
        }

        /// <summary>
        /// 生产入库完成
        /// </summary>
        /// <param name="id">自动入库ID</param>
        /// <returns></returns>
        [HttpPost]
        public async Task ComplatedInByTray(string id)
        {
            var audit = new AuditDTO();
            audit.Id = id;
            audit.StorId = _Op.Property.DefaultStorageId;
            audit.AuditUserId = _Op.UserId;
            audit.AuditTime = DateTime.Now;
            audit.AuditType = AuditType.Approve;
            await _tD_InStorageBus.Approve(audit);
        }

        [HttpPost]
        public async Task DeleteData(List<string> ids)
        {
            await _tD_InStorageBus.DeleteDataAsync(ids);
        }

        [HttpPost]
        public async Task Audit(AuditDTO audit)
        {
            audit.StorId = _Op.Property.DefaultStorageId;
            audit.AuditUserId = _Op.UserId;
            audit.AuditTime = DateTime.Now;
            if (audit.AuditType == AuditType.Approve)
                await _tD_InStorageBus.Approve(audit);
            else
                await _tD_InStorageBus.Reject(audit);
        }
        [HttpPost]
        public async Task InAudit(AuditDTO audit)
        {
            audit.StorId = _Op.Property.DefaultStorageId;
            audit.AuditUserId = _Op.UserId;
            audit.AuditTime = DateTime.Now;
            if (audit.AuditType == AuditType.Approve)
                await _tD_InStorageBus.InApprove(audit);
            else
                await _tD_InStorageBus.InReject(audit);
        }
        [HttpPost]
        public async Task InBlankTray(List<KeyValuePair<string, string>> listTray)
        {
            await _tD_InStorageBus.InBlankTray(listTray);
        }
        #endregion

        #region 无码入库打码

        /// <summary>
        /// 获取无码入库单的明细
        /// </summary>
        /// <param name="InStorageId">入库单Id</param>
        /// <returns></returns>
        [HttpPost]
        public async Task<List<NoCodeInStorageDetailDTO>> GetInStorageDetailList(string InStorageId)
        {
            return await _tD_InStorageBus.GetInStorageDetailListAsync(InStorageId);
        }

        /// <summary>
        /// 无码入库单打印条码
        /// </summary>
        /// <param name="data">打印机Id</param>
        /// <returns></returns>
        [HttpPost]
        public async Task PrintNoCodeInStorageDetailData(NoCodeInStorageDetailData data)
        {
            await _tD_InStorageBus.PrintNoCodeInStorageDetailDataAsync(data, _mongodbOptions);
        }

        #endregion

    }
}